package org.itstack.demo.design.door;

import com.alibaba.fastjson.JSON;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.itstack.demo.design.door.annotation.DoDoor;
import org.itstack.demo.design.door.config.StarterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.aspectj.lang.ProceedingJoinPoint;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Author: fanYuLe
 * @CreateTime: 2023-12-21  15:02
 * @Description:
 */
@Aspect
@Component
public class DoJoinPoint {
    private Logger logger = LoggerFactory.getLogger(DoJoinPoint.class);

    @Autowired
    private StarterService starterService;

    @Pointcut("@annotation(org.itstack.demo.design.door.annotation.DoDoor)")
    public void aopPoint(){}

    @Around("aopPoint()")
    public Object doRouter(ProceedingJoinPoint jp) throws Throwable {
        //获取内容
        Method method = getMethod(jp);
        DoDoor door = method.getAnnotation(DoDoor.class);
        //获取字段值
        String keyValue = getFiledValue(door.key(), jp.getArgs());

        logger.info("itstack door handler method：{} value：{}",method.getName(),keyValue);
        if(null==keyValue || "".equals(keyValue)){
            //目标方法执行
            return jp.proceed();
        }
        //配置内容
        String[] split = starterService.split(",");
        //白名单过滤
        for (String str : split) {
            if(keyValue.equals(str)){
                return jp.proceed();
            }
        }
        //拦截
        return returnObject(door,method);
    }

    private Method getMethod(JoinPoint jp) throws NoSuchMethodException {
        Signature sig = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return getClass(jp).getMethod(methodSignature.getName(),methodSignature.getParameterTypes());
    }

    private Class<? extends Object> getClass(JoinPoint jp){
        return jp.getTarget().getClass();
    }

    //获取属性值
    private String getFiledValue(String field,Object[] args){
        String fieldValue = null;
        for (Object arg : args) {
            try {
                if(null==fieldValue || "".equals(fieldValue)){
                    fieldValue = BeanUtils.getProperty(arg,field);
                }else {
                    break;
                }
            } catch (Exception e) {
                if(args.length==1){
                    return args[0].toString();
                }
            }
        }
        return fieldValue;
    }

    //返回对象
    private Object returnObject(DoDoor doGate,Method method) throws InstantiationException, IllegalAccessException {
        Class<?> returnType = method.getReturnType();
        String returnJson = doGate.returnJson();
        if ("".equals(returnJson)) {
            return returnType.newInstance();
        }
        return JSON.parseObject(returnJson, returnType);
    }
}
